#include <helpers\game\engine.h>

namespace DelGE
{
	namespace Helpers
	{
		namespace Game
		{
			Engine::Engine()
			{
				this->pSystem			= NULL;
				this->pGraphics			= NULL;
				this->pAudio			= NULL;
				this->pInput			= NULL;
			}

			Engine::~Engine()
			{
				this->pSystem			= NULL;
				this->pGraphics			= NULL;
				this->pAudio			= NULL;
				this->pInput			= NULL;
			}

			SystemModule* Engine::GetSystem()
			{
				return this->pSystem;
			}

			GraphicsModule* Engine::GetGraphics()
			{
				return this->pGraphics;
			}

			AudioModule* Engine::GetAudio()
			{
				return this->pAudio;
			}

			InputModule* Engine::GetInput()
			{
				return this->pInput;
			}

			void Engine::SetWindowHandle(SystemWindow *pWindowHandle)
			{
				this->pWindowHandle = pWindowHandle;
			}
			
			SystemWindow* Engine::GetWindowHandle()
			{
				return this->pWindowHandle;
			}

			int Engine::GetMouseX()
			{
				return this->pWindowHandle->ScreenPositionXToClientPositionX(this->pInput->GetMouseX());
			}

			int Engine::GetMouseY()
			{
				return this->pWindowHandle->ScreenPositionYToClientPositionY(this->pInput->GetMouseY());
			}

			void Engine::SetMousePosition(int iMouseX, int iMouseY)
			{
				iMouseX = this->pWindowHandle->ClientPositionXToScreenPositionX(iMouseX);
				iMouseY = this->pWindowHandle->ClientPositionYToScreenPositionY(iMouseY);
				this->pInput->SetMousePosition(iMouseX, iMouseY);
			}

			char Engine::GetChar()
			{
				char cCharacter = -1;

				if (!this->vCharacterBuffer.empty())
				{
					cCharacter = (char)this->vCharacterBuffer.back();
					this->vCharacterBuffer.pop_back();
				}

				return cCharacter;
			}
			
			void Engine::PushChar(char cCharacter)
			{
				if (this->vCharacterBuffer.size() > 256)
					this->vCharacterBuffer.erase(this->vCharacterBuffer.begin(), this->vCharacterBuffer.end());
				this->vCharacterBuffer.push_back(cCharacter);
			}

			void Engine::FlushChar()
			{
				this->vCharacterBuffer.erase(this->vCharacterBuffer.begin(), this->vCharacterBuffer.end());
			}

			void Engine::CreateDefaultModules()
			{
				try
				{
					this->pSystem		= new SystemModule();
					this->pGraphics		= new GraphicsModule();
					this->pInput		= new InputModule();
					this->pAudio		= new AudioModule();
				}
				catch (DelGEError& error)
				{
					cout << "Error: " << error.description << endl;
				}

				// system and input will load default interfaces, for
				// graphics and audio we will need to select and interface.
				#if defined (DELGE_PLATFORM_WIN32)
				// Default to opengl and fmod
				this->pGraphics->SetInterface(this->pGraphics->GetInterface_OpenGL());
				this->pAudio->SetInterface(this->pAudio->GetInterface_FMod());
				#endif
			}

			void Engine::DestroyDefaultModules()
			{
		
				// Make sure we have a mouse visiable on exit
				this->pSystem->ShowMouse();

				delete this->pSystem;	this->pSystem = NULL;
				delete this->pGraphics;	this->pGraphics = NULL;
				delete this->pAudio;	this->pAudio = NULL;
				delete this->pInput;	this->pInput = NULL;
			}

			void Engine::Update()
			{
				this->pInput->Update();
				this->pSystem->Update();
				this->pAudio->Update();
			}
		}
	}
}